﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Unicode;
using System.Threading.Tasks;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using BConsulService;
//using BConsulService;
using BEurekaService;
using BNacosService;
//using BConsulService;
using BusinessCache;
using BusinessRepository;
using ce.autofac.extension;
using IGeekFan.AspNetCore.Knife4jUI;
//using IGeekFan.AspNetCore.Knife4jUI;
using learun.util;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using NLog.Extensions.Logging;
using ProjectManApi.Extensions;
using ProjectManApi.mmm;
using Steeltoe.Discovery.Client;
using Swashbuckle.AspNetCore.SwaggerUI;
using IApplicationLifetime = Microsoft.AspNetCore.Hosting.IApplicationLifetime;
//using IApplicationLifetime = Microsoft.AspNetCore.Hosting.IApplicationLifetime;


namespace ProjectManApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllers();
            //添加日期格式处理，将日期格式统一修改为"yyyy-MM-dd HH:mm:ss"格式
            services.AddControllersWithViews()
            .AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";

                //统一大小写好像没效果
                //options.SerializerSettings.ContractResolver = new LowercaseContractResolver(); 
            });


            //启用session
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            //注册跨域服务    
            services.AddCors(options =>
            {
                //添加跨域策略
                options.AddPolicy("any", builder =>
                {
                    builder.AllowAnyOrigin() //允许所有来源
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials();//cookie
                });
            });


            //services.AddHttpsRedirection(opt => opt.HttpsPort = 443);

            //这里添加了Mvc
            //services.AddMvc(option =>
            //{
            //    option.Filters.Add(typeof(ExceptionFilter));
            //}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
            services.AddMvc()
                .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

            #region 启用Swagger
            services.ConfigureSwagger();
            #endregion

            #region 将配置绑定到JwtConfig实例中
            services.Configure<JWTConfig>(Configuration.GetSection("JWT"));



            JWTConfig jwtConfig = new JWTConfig();

            Configuration.GetSection("JWT").Bind(jwtConfig);



            //ConfigureJwt
            //services.ConfigureJwt(jwtConfig);
            #endregion

            #region AddNacos 注册中心
            //services.Configure<EurekaServicexml>(Configuration.GetSection("ConsulService"));//nameof(EurekaServicexml)
            //Eureka
            //services.AddEurekaService(null);

            //consul
            //services.Configure<ConsulService>(Configuration.GetSection(nameof(ConsulService)));

            //Nacos
            //NacosService nacosService = new NacosService();
            //Configuration.GetSection("NacosService").Bind(nacosService);
            //services.AddNacosService(Configuration);
            services.AddNacosAspNetCore(Configuration);

            #endregion
        }

        //IOC
        public void ConfigureContainer(ContainerBuilder builder)
        {
            // 配置autofac依赖注入
            //builder.RegisterIBLL();
            DbRegister.Register(builder);
            builder.RegisterType(typeof(CacheByRedis)).As(typeof(ICache)).SingleInstance();
            builder.RegisterType(typeof(Operator)).As(typeof(IOperator)).SingleInstance();
            //builder.RegisterType(typeof(LogBLL)).As(typeof(LogIBLL)).SingleInstance();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApplicationLifetime lifetime, ILoggerFactory loggerFactory)//, IOptions<ConsulService> consulService
        //consulService
        //public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApplicationLifetime lifetime, IOptions<ConsulService> consulService)
        //EurekaServicexml
        //public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptions<EurekaServicexml> fuzlService)
        {
            //IOC
            IocManager.Instance.Container = app.ApplicationServices.GetAutofacRoot();

            string baseDir = env.ContentRootPath;
            ConfigHelper.SetValue("baseDir", baseDir);


            //ConfigHelper.SetValue("WriteLogDB", Configuration.GetSection("ServerOp:WriteLogDB").Value);


            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
              
            }

            if (Configuration.GetSection("UseSwagger").Value == "true")
            {
                #region Swagger
                //MiddlewareSwagger
                app.UseSwagger();
                //Middleware SwaggerUI Swagger JSON
                //1 UseSwaggerUI
                app.UseSwaggerUI(c =>
                {
                    c.SwaggerEndpoint("swagger/v1/swagger.json", "大三资CoreWebApi");
                    //c.SwaggerEndpoint("/swagger/ys/swagger.json", "资产预算");
                    //c.SwaggerEndpoint("/swagger/gz/swagger.json", "资产购置");
                    //c.SwaggerEndpoint("/swagger/ly/swagger.json", "资产领用");
                    c.RoutePrefix = string.Empty;//
                });


                #endregion
            }

            //一直报307 移到下面试下
            //https
            //app.UseHttpsRedirection();

            //添加全局日志
            app.UseLogMiddleware();

            //路由
            app.UseRouting();

            //跨域 需要放在 UseRouting 下面
            //app.UseCors("any");

            #region 认证授权
            //认证
            //app.UseAuthentication();

            //授权
            app.UseAuthorization();

            //https
            app.UseHttpsRedirection();

            // 自定义授权，放在 app.UseAuthorization()之后 主要用于PrincipalAccessor 
            app.UseMiddleware<JwtAuthorizeMiddleware>();
            #endregion



            #region 注册中心
            //Nacos
            //var nacosConfigClient = app.ApplicationServices.GetRequiredService<Nacos.INacosConfigClient>();
            //app.UseNacosService(fuzlService);
            //app.UseNacosServiceCore1(fuzlService);
            //app.UseNacosAspNetCore();

            //Eureka
            //app.UseEurekaService(fuzlService);

            //Consul
            //app.UseConsulService(lifetime,consulService);
            #endregion


            //路由
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();

                //UseKnife4UI
                //endpoints.MapSwagger("{documentName}/api-docs");
            });
            //loggerFactory.AddNLog();


            //app.UseMvc();

            //Add Steeltoe Discovery Client service
            //app.UseDiscoveryClient();
        }
    }
}
